<template>
  <div>App</div>
  <p>a--->{{ a }}</p>
  <button @click="fn">按钮</button>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "App",
});
</script>

<script setup lang="ts">
import { ref, type Ref } from "vue";
/* 
  如果直接在setup中定义变量,则这个值没有响应式的能力
  setup的函数this都是指向undefined
*/
/* 
  1.使用ref方法来创建响应式数据
  2.接受一个值，返回一个响应式的、可更改的ref对象
  3.如果接受的是ref对象，则直接把这个ref对象返回
  4.如果接受的是一个非ref对象，则实例化refImpl构造函数，得到一个实例化ref对象，对象也是通过getter和setter来进行收集依赖和触发依赖更新
  5.ref对象中的dep属性就是收集的依赖，ref对象中的value属性就是我们ref保存的值
  6.想要在js中使用ref对象的值，必须要添加value属性才能拿到，在模板中使用ref对象的值可以省略value
*/
class RefImpl {
  constructor(value: any) {
    // 如果接受的参数是ref对象，则直接返回ref对象
    if (isRef(value)) {
      return value;
    }
    // 如果接收的不是ref对象，则直接返回实例化对象
    // 实例化对象中的dep属性保存的就是所有的依赖
    this.dep = new Set();
    this.value = value;
  }

  // 类上有getter函数
  get() {
    // 收集依赖
    return this;
  }
  set() {
    // 通知所有依赖的更新
    this.value = value;
  }
}
// 定义一个值并限制类型方式1
let a: Ref<number> = ref(1);
const fn = function () {
  console.log(a);
  a.value++;
};

function Person(){
  this.name = name;
  this.value = value
  // 构造函数中如果没有返回值或者返回一个基本类型值,则构造函数还是实例化
  // 构造函数中如果返回的是对象类型,则构造函数不在返回实例化对象了，而是返回这个对象
}
</script>

<style scoped></style>
